home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / dispimg.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  14KB  |  615 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    dispimg -
  19.  *        General package for the display of images on all machines.
  20.  *    This package deals with the problems of dithering RGB images on
  21.  *    to the screens of all IRISes from the very low end to the 
  22.  *    high end.  This is NOT what you need if you want to display
  23.  *    iris images on a machine with RGBmode().  Take a look at
  24.  *    fastimg.c.
  25.  *
  26.  *                Paul Haeberli - 1988
  27.  */
  28. #include "gl.h"
  29. #include "get.h"
  30. #include "dispimg.h"
  31. #include "image.h"
  32. #include "gfxmach.h"
  33.  
  34. extern unsigned char red_map[256];
  35. extern unsigned char green_map[256];
  36. extern unsigned char blue_map[256];
  37. extern unsigned char red_inverse[256];
  38. extern unsigned char green_inverse[256];
  39. extern unsigned char blue_inverse[256];
  40. extern unsigned char grey_inverse[256];
  41.  
  42. /* kinds of image files */
  43.  
  44. #define BWIMG        0
  45. #define RGBIMG        1
  46. #define SCREENIMG    2
  47.  
  48. static prefmode[6][3] = {
  49. /*          BW             RGB       SCREEN             */
  50.     DI_WRITEPIXELS,    DI_WRITEPIXELS, DI_WRITEPIXELS, /* MACH3D     */
  51.     DI_WRITEPIXELS,    DI_LRECTWRITE,    DI_WRITEPIXELS, /* MACH4D     */
  52.     DI_LRECTWRITE,    DI_LRECTWRITE,    DI_RECTWRITE,     /* MACH4DGT     */
  53.     DI_WRITEPIXELS,    DI_LRECTWRITE,    DI_WRITEPIXELS,    /* MACH4DPI     */
  54.     DI_WRITEPIXELS,    DI_WRITEPIXELS,    DI_WRITEPIXELS,    /* MACH4D8     */
  55.     DI_LRECTWRITE,    DI_LRECTWRITE,    DI_RECTWRITE,     /* MACH4DVGX     */
  56. };
  57.  
  58. #define XSIZE    4
  59. #define YSIZE    4
  60. #define TOTAL        (XSIZE*YSIZE)
  61. #define WRAPY(y)    ((y)%YSIZE)
  62. #define WRAPX(x)    ((x)%XSIZE)
  63.  
  64. static short dithmat[YSIZE][XSIZE] = {
  65.     0, 8, 2, 10,
  66.     12, 4, 14, 6,
  67.     3, 11, 1, 9,
  68.     15, 7, 13, 5,
  69. };
  70.  
  71. static int imgtype;
  72. static short **bwtab;
  73. static short **rtab;
  74. static short **gtab;
  75. static short **btab;
  76.  
  77. static inchack()    /* just to get externs defined */
  78. {
  79.      rgbi(0,0,0);
  80. }
  81.  
  82. short **makedittab(levels,mult,add)
  83. int levels, mult, add;
  84. {
  85.     int val;
  86.     int nshades;
  87.     int i, j, k;
  88.     int matval, tabval;
  89.     short **tab;
  90.  
  91.     nshades = XSIZE*YSIZE*(levels-1)+1;
  92.     tab = (short **)mymalloc(YSIZE*sizeof(short *));
  93.     for(j=0; j<YSIZE; j++) {
  94.     tab[j] = (short *)mymalloc(XSIZE*256*sizeof(short));
  95.     for(i=0; i<XSIZE; i++ ) {
  96.         matval = dithmat[i][j]; 
  97.         for(k=0; k<256; k++) {
  98.         val = (nshades*k)/255;
  99.         if(val==nshades)
  100.             val = nshades-1;
  101.         if((val%TOTAL)>matval) 
  102.             tabval =  (val/TOTAL)+1;
  103.         else 
  104.             tabval = (val/TOTAL);
  105.         tabval *= mult;
  106.         tabval += add;
  107.         tab[j][256*i+k] = tabval;
  108.         }
  109.     }
  110.     }
  111.     return tab;
  112. }
  113.  
  114. imagetype(image)
  115. IMAGE *image;
  116. {
  117.     if(image->zsize>=3)
  118.     return RGBIMG;
  119.     if(image->colormap == CM_SCREEN)
  120.     return SCREENIMG;
  121.     else
  122.     return BWIMG;
  123. }
  124.  
  125. setimagemode(image)
  126. IMAGE *image;
  127. {
  128.     int type, dispmode, curdispmode;
  129.  
  130.     type = imagetype(image);
  131.     dispmode = prefdrawmode(type);
  132.     curdispmode = getdisplaymode();
  133.     switch(dispmode) {
  134.        case DI_LRECTWRITE:
  135.         if(curdispmode != DMRGB && curdispmode != DMRGBDOUBLE)
  136.         pseudorgb();
  137.         break;
  138.        case DI_WRITEPIXELS:
  139.        case DI_RECTWRITE:
  140.         if(curdispmode != DMSINGLE && curdispmode != DMDOUBLE) {
  141.         singlebuffer();
  142.         gconfig();
  143.         }
  144.         break;
  145.     }
  146. }
  147.  
  148. prefdrawmode(type)
  149. int type;
  150. {
  151.     int val, mach; 
  152.     
  153.     mach = gfxmachine();
  154.     val = prefmode[mach][type];
  155.     return val;
  156. }
  157.  
  158. drawimage(di,xorg,yorg)
  159. DISPIMAGE *di;
  160. int xorg, yorg;
  161. {
  162.     int y, step;
  163.     unsigned short *sptr;
  164.     unsigned char *rptr, *gptr, *bptr;
  165.     short vpx1, vpx2, vpy1, vpy2;
  166.  
  167.     getviewport(&vpx1,&vpx2,&vpy1,&vpy2);
  168.     switch(di->type) {
  169.     case DI_WRITEPIXELS:
  170.         sptr = (unsigned short *)di->data;
  171.             pushmatrix();
  172.         ortho2(-0.5,(vpx2-vpx1)+0.5,-0.5,(vpy2-vpy1)+0.5);
  173.         for(y=0; y<di->ysize; y++) {
  174.         cmov2i(xorg,yorg+y);
  175.         writepixels(di->xsize,sptr);
  176.         sptr += di->xsize;
  177.         }
  178.             popmatrix();
  179.         break;
  180.     case DI_RECTWRITE:
  181.         rectwrite(xorg+vpx1,yorg+vpy1,
  182.                   xorg+di->xsize-1,yorg+di->ysize-1,(unsigned short *)di->data);
  183.         break;
  184.     case DI_LRECTWRITE:
  185.         lrectwrite(xorg+vpx1,yorg+vpy1,
  186.                xorg+di->xsize-1,yorg+di->ysize-1,(unsigned long *)di->data);
  187.         break;
  188.     }
  189. }
  190.  
  191. DISPIMAGE *makedisprgn(image,x1,x2,y1,y2,show,xorg,yorg)
  192. IMAGE *image;
  193. unsigned int x1, x2, y1, y2;
  194. int show, xorg, yorg;
  195. {
  196.     DISPIMAGE *di;
  197.     int xsize, ysize, y;
  198.     int imgtype;
  199.     unsigned char *cptr;
  200.     unsigned short *sptr;
  201.     unsigned long *lptr;
  202.     short *sbuf, *rbuf, *gbuf, *bbuf;
  203.     short vpx1, vpx2, vpy1, vpy2;
  204.  
  205.     di = (DISPIMAGE *)mymalloc(sizeof(DISPIMAGE));
  206.     xsize = x2-x1+1;
  207.     ysize = y2-y1+1;
  208.     di->xsize = xsize;
  209.     di->ysize = ysize;
  210.     imgtype = imagetype(image);
  211.     di->type = prefdrawmode(imgtype);
  212.     switch(di->type) {
  213.     case DI_WRITEPIXELS:
  214.     case DI_RECTWRITE:
  215.         di->data = (unsigned char *)mymalloc(xsize*ysize*sizeof(short));
  216.         break;
  217.     case DI_LRECTWRITE:
  218.         di->data = (unsigned char *)mymalloc(xsize*ysize*sizeof(long));
  219.         break;
  220.     }
  221.     if(!di->data) {
  222.      fprintf(stderr,"makedisprgn: out of memory\n");
  223.      return 0;
  224.     }
  225.  
  226.     if(show) {
  227.         getviewport(&vpx1,&vpx2,&vpy1,&vpy2);
  228.     pushmatrix();
  229.     ortho2(-0.5,(vpx2-vpx1)+0.5,-0.5,(vpy2-vpy1)+0.5);
  230.     }
  231.     switch(imgtype) {
  232.     case BWIMG:
  233.         switch(di->type) {
  234.          case  DI_WRITEPIXELS:
  235.             sptr = (unsigned short *)di->data;
  236.             sbuf = (short *)mymalloc(image->xsize*sizeof(short));
  237.             for(y=0; y<ysize; y++) {
  238.             getrow(image,sbuf,y+y1,0);
  239.             bwtowp(sbuf+x1,sptr,xsize,y);
  240.             if(show) {
  241.                 cmov2i(xorg,yorg+y);
  242.                 writepixels(xsize,sptr);
  243.             }
  244.             sptr += xsize;
  245.             }
  246.             free(sbuf);
  247.             break;
  248.         case  DI_LRECTWRITE:
  249.             lptr = (unsigned long *)di->data;
  250.                 rbuf = (short *)mymalloc(image->xsize*sizeof(short));
  251.             for(y=0; y<ysize; y++) {
  252.             getrow(image,rbuf,y+y1,0);
  253.             bwtocpack(rbuf+x1,lptr,xsize);
  254.                 if(show) 
  255.                 lrectwrite(xorg,yorg+y,xorg+xsize-1,yorg+y,lptr);
  256.             lptr += xsize;
  257.             }
  258.             free(rbuf);
  259.             break;
  260.         }
  261.         break;
  262.     case RGBIMG:
  263.         switch(di->type) {
  264.         case DI_WRITEPIXELS:
  265.         case DI_RECTWRITE:
  266.             sptr = (unsigned short *)di->data;
  267.                 rbuf = (short *)mymalloc(image->xsize*sizeof(short));
  268.                 gbuf = (short *)mymalloc(image->xsize*sizeof(short));
  269.                 bbuf = (short *)mymalloc(image->xsize*sizeof(short));
  270.             for(y=0; y<ysize; y++) {
  271.             getrow(image,rbuf,y+y1,0);
  272.             getrow(image,gbuf,y+y1,1);
  273.             getrow(image,bbuf,y+y1,2);
  274.             rgbtowp(rbuf+x1,gbuf+x1,bbuf+x1,sptr,xsize,y);
  275.                 if(show) {
  276.                     cmov2i(xorg,yorg+y);
  277.                     writepixels(xsize,sptr);
  278.                 }
  279.             sptr += xsize;
  280.             }
  281.             free(rbuf);
  282.             free(gbuf);
  283.             free(bbuf);
  284.             break;
  285.         case DI_LRECTWRITE:
  286.             lptr = (unsigned long *)di->data;
  287.                 rbuf = (short *)mymalloc(image->xsize*sizeof(short));
  288.                 gbuf = (short *)mymalloc(image->xsize*sizeof(short));
  289.                 bbuf = (short *)mymalloc(image->xsize*sizeof(short));
  290.             for(y=0; y<ysize; y++) {
  291.             getrow(image,rbuf,y+y1,0);
  292.             getrow(image,gbuf,y+y1,1);
  293.             getrow(image,bbuf,y+y1,2);
  294.             rgbtocpack(rbuf+x1,gbuf+x1,bbuf+x1,lptr,xsize);
  295.                 if(show) 
  296.                 lrectwrite(xorg,yorg+y,xorg+xsize-1,yorg+y,lptr);
  297.             lptr += xsize;
  298.             }
  299.             free(rbuf);
  300.             free(gbuf);
  301.             free(bbuf);
  302.             break;
  303.         }
  304.         break;
  305.     case SCREENIMG:
  306.         sptr = (unsigned short *)di->data;
  307.         sbuf = (short *)mymalloc(image->xsize*sizeof(short));
  308.         for(y=0; y<ysize; y++) {
  309.         getrow(image,sbuf,y+y1,0);
  310.         wptowp(sbuf+x1,sptr,xsize);
  311.         if(show) {
  312.             cmov2i(xorg,yorg+y);
  313.             writepixels(xsize,(unsigned short *)sbuf+x1);
  314.         }
  315.         sptr += xsize;
  316.         }
  317.         free(sbuf);
  318.         break;
  319.     }
  320.     if(show) 
  321.     popmatrix();
  322.     return di;
  323. }
  324.  
  325. DISPIMAGE *makedisp(image)
  326. IMAGE *image;
  327. {
  328.     return makedisprgn(image,0,image->xsize-1,0,image->ysize-1,0,0,0);
  329. }
  330.  
  331. bwtowp(bw,wp,n,y)
  332. unsigned short *bw, *wp;
  333. int n, y;
  334. {
  335.     short *bwbase;
  336.     int *maptab;
  337.     int i, cur, nshades;
  338.     int ix, iy;
  339.  
  340.     if(!bwtab) {
  341.     maptab = (int *)mymalloc(256*sizeof(int));
  342.     cur = 100000;
  343.     nshades = 0;
  344.     for(i=0; i<256; i++) {
  345.         if(grey_inverse[i] != cur) {
  346.         cur = grey_inverse[i];
  347.         maptab[nshades] = cur;
  348.         nshades++;
  349.         }
  350.     }
  351.     bwtab= makedittab(nshades,1,0);
  352.     for(iy=0; iy<YSIZE; iy++) {
  353.         for(ix=0; ix<XSIZE; ix++) {
  354.         bwbase = bwtab[iy]+256*ix;
  355.         for(i=0; i<256; i++) 
  356.             bwbase[i] = maptab[bwbase[i]];
  357.         }
  358.     }
  359.     free(maptab);
  360.     }
  361.     bwbase = bwtab[WRAPY(y)];
  362.     while(n) {
  363.     if(n>=XSIZE) {
  364.         wp[0] = bwbase[bw[0] + 0];
  365.         wp[1] = bwbase[bw[1] + 256];
  366.         wp[2] = bwbase[bw[2] + 512];
  367.         wp[3] = bwbase[bw[3] + 768];
  368.         wp+=4;
  369.         bw+=4;
  370.         n -= XSIZE;
  371.     } else {
  372.         *wp++ = bwbase[*bw++];
  373.         bwbase += 256;
  374.         n--;
  375.     }
  376.     }
  377. }
  378.  
  379. makedittabs()
  380. {
  381.     rtab = makedittab(5,8,0);
  382.     btab = makedittab(5,40,0);
  383.     gtab = makedittab(8,1,56);
  384. }
  385.  
  386. rgbtowp(r,g,b,wp,n,y)
  387. unsigned short *r, *g, *b;
  388. short *wp;
  389. int n, y;
  390. {
  391.     short *rbase;
  392.     short *gbase;
  393.     short *bbase;
  394.  
  395.     if(!rtab) 
  396.     makedittabs();
  397.     rbase = rtab[WRAPY(y)];
  398.     gbase = gtab[WRAPY(y)];
  399.     bbase = btab[WRAPY(y)];
  400.     while(n) {
  401.     if(n>=XSIZE) {
  402.         wp[0] = rbase[r[0] +   0] + gbase[g[0] +   0] + bbase[b[0] +   0];
  403.         wp[1] = rbase[r[1] + 256] + gbase[g[1] + 256] + bbase[b[1] + 256];
  404.         wp[2] = rbase[r[2] + 512] + gbase[g[2] + 512] + bbase[b[2] + 512];
  405.         wp[3] = rbase[r[3] + 768] + gbase[g[3] + 768] + bbase[b[3] + 768];
  406.         wp += 4;
  407.         r += 4;
  408.         g += 4;
  409.         b += 4;
  410.         n -= XSIZE;
  411.     } else {
  412.         *wp++ = rbase[*r++] + gbase[*g++] + bbase[*b++];
  413.         rbase += 256;
  414.         gbase += 256;
  415.         bbase += 256;
  416.         n--;
  417.     }
  418.     }
  419. }
  420.  
  421. wptowp(sptr,dptr,n)
  422. short *sptr, *dptr; 
  423. int n;
  424. {
  425.     bcopy(sptr,dptr,n*sizeof(short));
  426. }
  427.  
  428. DISPIMAGE *readdispimage(name)
  429. char *name;
  430. {
  431.     char fullname[100];
  432.     IMAGE *image;
  433.  
  434.     findname(name,fullname,"GFXPATH");
  435.     image = iopen(fullname,"r");
  436.     if(!image) {
  437.     fprintf(stderr,"readdispimage: can't find image %s along GFXPATH\n",name);
  438.     exit(1);
  439.     }
  440.     return makedisp(image);
  441. }
  442.  
  443. static unsigned short *sbuf; 
  444. static unsigned long *lbuf; 
  445. static int ditxzoom = 1;
  446. static int dityzoom = 1;
  447.  
  448. ditrectzoom(xzoom,yzoom)
  449. float xzoom,yzoom;
  450. {
  451.     ditxzoom = xzoom+0.49;
  452.     dityzoom = yzoom+0.49;
  453. }
  454.  
  455. ditlrectwrite(x1,y1,x2,y2,buf)
  456. int x1, y1, x2, y2;
  457. unsigned long *buf;
  458. {
  459.     int y, ry, my, n;
  460.     int scrxsize;
  461.  
  462.     if(!sbuf) {
  463.     scrxsize = getgdesc(GD_XPMAX);
  464.     sbuf = (unsigned short *)mymalloc(scrxsize*sizeof(short));
  465.     lbuf = (unsigned long *)mymalloc(scrxsize*sizeof(long));
  466.     makedittabs();
  467.     }
  468.     n = x2-x1+1;
  469.     if(ditxzoom == 1 && dityzoom == 1) {
  470.     for(y=y1; y<=y2; y++) {
  471.         ditlrow(x1,y,buf,sbuf,n);
  472.         rectwrite(x1,y,x2,y,sbuf);
  473.         buf+=n;
  474.     }
  475.     } else {
  476.     x2 = x1+(ditxzoom*n)-1;
  477.     my = y1;
  478.     for(y=y1; y<=y2; y++) {
  479.         replrow(buf,lbuf,n,ditxzoom);
  480.         for(ry=0; ry<dityzoom; ry++) {
  481.         ditlrow(x1,my,lbuf,sbuf,ditxzoom*n);
  482.         rectwrite(x1,my,x2,my,sbuf);
  483.         my++;
  484.         }
  485.         buf+=n;
  486.     }
  487.     }
  488. }
  489.  
  490. ditlrow(x,y,buf,sbuf,n)
  491. int x, y;
  492. unsigned char *buf;
  493. unsigned short *sbuf;
  494. int n;
  495. {
  496.     short offset;
  497.     int s;
  498.     short *rbase;
  499.     short *gbase;
  500.     short *bbase;
  501.  
  502.     rbase = rtab[WRAPY(y)];
  503.     gbase = gtab[WRAPY(y)];
  504.     bbase = btab[WRAPY(y)];
  505.  
  506. /* do the first few pixels */
  507.     s = WRAPX(x);
  508.     if(s) {
  509.     offset = 256*s;
  510.     s = 4-s;
  511.     while(n && s) {
  512.         *sbuf++ = rbase[buf[3] + offset] + 
  513.                 gbase[buf[2] + offset] + 
  514.                     bbase[buf[1] + offset];
  515.         buf += 4;
  516.         offset += 256;
  517.         n--;
  518.         s--;
  519.     }
  520.     }
  521.  
  522. /* do the rest */
  523.     offset = 0;
  524.     while(n) {
  525.     if(n>=4) {
  526.         *sbuf++ = rbase[buf[3+0] +   0] + 
  527.                 gbase[buf[2+0] +   0] + 
  528.                     bbase[buf[1+0] +   0];
  529.         *sbuf++ = rbase[buf[3+4] + 256] + 
  530.                 gbase[buf[2+4] + 256] + 
  531.                     bbase[buf[1+4] + 256];
  532.         *sbuf++ = rbase[buf[3+8] + 512] + 
  533.                 gbase[buf[2+8] + 512] + 
  534.                     bbase[buf[1+8] + 512];
  535.         *sbuf++ = rbase[buf[3+12] + 768] + 
  536.                 gbase[buf[2+12] + 768] + 
  537.                     bbase[buf[1+12] + 768];
  538.         buf += 16;
  539.         n -= 4;
  540.     } else {
  541.         *sbuf++ = rbase[buf[3] + offset] + 
  542.                 gbase[buf[2] + offset] + 
  543.                     bbase[buf[1] + offset];
  544.         buf += 4;
  545.         offset += 256;
  546.         n--;
  547.     }
  548.     }
  549. }
  550.  
  551. ditpnt2i(x,y,c)
  552. int x, y;
  553. long c;
  554. {
  555.     short *rbase;
  556.     short *gbase;
  557.     short *bbase;
  558.     short r, g, b, offset;
  559.  
  560.     if(!rtab) 
  561.     makedittabs();
  562.     rbase = rtab[WRAPY(y)];
  563.     gbase = gtab[WRAPY(y)];
  564.     bbase = btab[WRAPY(y)];
  565.     offset = 256*WRAPX(x);
  566.     r = offset+((c>>0)&0xff);
  567.     g = offset+((c>>8)&0xff);
  568.     b = offset+((c>>16)&0xff);
  569.     color(rbase[r] + gbase[g] + bbase[b]);
  570.     pnt2i(x,y);
  571. }
  572.  
  573. replrow(buf,mbuf,n,mag)
  574. long *buf, *mbuf;
  575. int n, mag;
  576. {
  577.     int m;
  578.     long val;
  579.  
  580.     switch(mag) {
  581.     case 1:
  582.         bcopy(buf,mbuf,n*sizeof(long)); 
  583.         break;
  584.     case 2:
  585.         while(n--) {
  586.         *mbuf++ = *buf;
  587.         *mbuf++ = *buf++;
  588.         }
  589.         break;
  590.     case 3:
  591.         while(n--) {
  592.         *mbuf++ = *buf;
  593.         *mbuf++ = *buf;
  594.         *mbuf++ = *buf++;
  595.         }
  596.         break;
  597.     case 4:
  598.         while(n--) {
  599.         *mbuf++ = *buf;
  600.         *mbuf++ = *buf;
  601.         *mbuf++ = *buf;
  602.         *mbuf++ = *buf++;
  603.         }
  604.         break;
  605.     default:
  606.         while(n--) {
  607.         m = mag;
  608.         val = *buf++;
  609.         while(m--)
  610.             *mbuf++ = val;
  611.         }
  612.         break;
  613.     }
  614. }
  615.